<template>
  <div class="terminal-container">
    <div class="dashboard-card" style="padding: 0; height: calc(100vh - 140px);">
      <div class="terminal-header">
        <div class="terminal-info">
          <el-icon :size="20"><Monitor /></el-icon>
          <span class="terminal-title">SSH终端 - {{ hostInfo.hostname }} ({{ hostInfo.ip }})</span>
        </div>
        <div class="terminal-actions">
          <el-button size="small" @click="reconnect">
            <el-icon><Refresh /></el-icon> 重连
          </el-button>
          <el-button size="small" @click="clearTerminal">
            <el-icon><Delete /></el-icon> 清屏
          </el-button>
          <el-button size="small" type="danger" @click="disconnect">
            <el-icon><Close /></el-icon> 断开
          </el-button>
        </div>
      </div>
      
      <div class="terminal-status" v-if="statusMessage">
        <el-alert :title="statusMessage" :type="statusType" :closable="false" center />
      </div>
      
      <div ref="terminalRef" class="terminal-body"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import { hostAPI } from '@/api'

const route = useRoute()
const router = useRouter()
const terminalRef = ref(null)
const hostInfo = ref({ hostname: '', ip: '' })
const statusMessage = ref('正在连接...')
const statusType = ref('info')

let terminal = null
let fitAddon = null
let ws = null

const initTerminal = () => {
  terminal = new Terminal({
    fontSize: 14,
    fontFamily: 'Monaco, Menlo, "Courier New", monospace',
    theme: {
      background: '#0a1929',
      foreground: '#ffffff',
      cursor: '#3a84ff',
      selection: 'rgba(58, 132, 255, 0.3)'
    },
    cursorBlink: true,
    cursorStyle: 'block',
    scrollback: 1000
  })

  fitAddon = new FitAddon()
  terminal.loadAddon(fitAddon)
  terminal.open(terminalRef.value)
  fitAddon.fit()

  terminal.onData(data => {
    if (ws && ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: 'stdin', data: data }))
    }
  })

  window.addEventListener('resize', handleResize)
}

const handleResize = () => {
  if (fitAddon) {
    fitAddon.fit()
    if (ws && ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({
        type: 'resize',
        cols: terminal.cols,
        rows: terminal.rows
      }))
    }
  }
}

const connectWebSocket = () => {
  const hostId = route.params.id
  const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  const wsUrl = `${protocol}//${window.location.hostname}:8000/ws/ssh/${hostId}/`

  ws = new WebSocket(wsUrl)

  ws.onopen = () => {
    statusMessage.value = '连接成功'
    statusType.value = 'success'
    setTimeout(() => {
      statusMessage.value = ''
    }, 2000)
  }

  ws.onmessage = (event) => {
    try {
      const message = JSON.parse(event.data)
      
      if (message.type === 'connected') {
        terminal.writeln('\r\n\x1b[32m✓ SSH连接成功\x1b[0m\r\n')
      } else if (message.type === 'stdout') {
        terminal.write(message.data)
      } else if (message.type === 'error') {
        terminal.writeln(`\r\n\x1b[31m✗ 错误: ${message.message}\x1b[0m\r\n`)
        statusMessage.value = `错误: ${message.message}`
        statusType.value = 'error'
      }
    } catch (error) {
      console.error('解析消息失败:', error)
    }
  }

  ws.onerror = () => {
    statusMessage.value = 'WebSocket连接错误'
    statusType.value = 'error'
    terminal.writeln('\r\n\x1b[31m✗ WebSocket连接错误\x1b[0m\r\n')
  }

  ws.onclose = () => {
    statusMessage.value = '连接已断开'
    statusType.value = 'warning'
    terminal.writeln('\r\n\x1b[33m⚠ 连接已断开\x1b[0m\r\n')
  }
}

const reconnect = () => {
  if (ws) ws.close()
  if (terminal) terminal.clear()
  statusMessage.value = '正在重新连接...'
  statusType.value = 'info'
  setTimeout(() => connectWebSocket(), 500)
}

const clearTerminal = () => {
  if (terminal) terminal.clear()
}

const disconnect = () => {
  if (ws) ws.close()
  router.push('/hosts')
}

const fetchHostInfo = async () => {
  try {
    const data = await hostAPI.get(route.params.id)
    hostInfo.value = data
  } catch (error) {
    ElMessage.error('获取主机信息失败')
  }
}

onMounted(async () => {
  await fetchHostInfo()
  initTerminal()
  connectWebSocket()
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  if (ws) ws.close()
  if (terminal) terminal.dispose()
})
</script>

<style scoped>
.terminal-container {
  width: 100%;
  height: calc(100vh - 140px);
}

.terminal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
  background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
  border-bottom: 1px solid rgba(58, 132, 255, 0.3);
}

.terminal-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.terminal-title {
  font-size: 16px;
  font-weight: 500;
  color: #fff;
}

.terminal-status {
  padding: 10px 20px;
}

.terminal-body {
  height: calc(100% - 60px);
  padding: 10px;
  overflow: hidden;
}

.terminal-body :deep(.xterm) {
  height: 100%;
}

.terminal-body :deep(.xterm-viewport) {
  background: #0a1929 !important;
}
</style>
